import datetime
import random
import re

from info.lib.yuntongxun.sms import CCP
from info.models import User
from info.utits.response_code import RET
from .import passport_bp
from flask import request, current_app, abort, make_response, jsonify, session
from info import redis_store, constants, db
from info.utits.captcha import captcha

@passport_bp.route('/image_code')
def get_image_code():
    """
    现在是编写短信验证码
    获取参数
        获取uuid

    校验参数
        验证UUID有没有值
    逻辑处理
        生成图片跟图片验证码
        把图片验证码跟UUID关联起来
    返回值
        返回图片验证码
    :return:
    """
    code_id = request.args.get('code_id','')
    if not code_id:
        return abort(404)

    image_name,real_image_code,image_data=captcha.captcha.generate_captcha()
    # 能够获取到三个数值，分别是图片的名字，验证吗，图片
    try:
        redis_store.setex("imageCodeId_%s"%code_id,constants.IMAGE_CODE_REDIS_EXPIRES,real_image_code)
    except Exception as e:
        current_app.logger.error(e)
        abort(500)
    response=make_response(image_data)
    response.headers["Content-Type"] = 'image/JPEG'
    return response


@passport_bp.route('/register',methods=['POST'])
def register():
    """
    现在要做的短信验证码
    1.获取数据
        获取图片验证码
        手机号码
        获取未加密密码
    2.校验数据
        判断图片验证码是否为空
        判断手机号是否为空
        正则验证
    3.处理数据
        根据sms_code_手机号码，去redis中获取短信验证码
            有值：删除
            没有值：过期了
        拿用户的短信验证码进行校验
            一致：使用User模型创建用户对象
            不一致：提示短信验证码错误
            一般需求：用户注册成功后，需要默认登录成功，记录session数据
    4.返回json数据
        返回Json数据
    :return:
    """
    param_dict=request.json
    mobile=param_dict.get("mobile","")
    smscode=param_dict.get("smscode","")
    password=param_dict.get("password","")
    if not ([smscode,mobile,password]):
        return jsonify(errno=RET.PARAMERR,error="参数不足")

    if not re.match('1[3578][0-9]{9}',mobile):
        return jsonify(errno=RET.PARAMERR,error="手机号码格式错误")
    try:
        real_smscode=redis_store.get('SMS_CODE_%s'% mobile)
    except Exception as e:
        return jsonify(errno=RET.DBERR, error="查询真实短信验证码出现错误")
    if not real_smscode:

        return jsonify(errno=RET.NODATA,error="数据已经过期了")
    else:
        redis_store.delete('SMS_CODE_%s'% mobile)

    real_smscode = str(real_smscode, encoding="utf8")
    if real_smscode != smscode:

        return jsonify(errno=RET.DATAERR,error='短信验证码填写错误')

    user = User()

    user.nick_name=mobile
    user.mobile=mobile
    try:
        user.last_login=datetime.datetime.now()
    except Exception as e:
        return print('错误')
    user.password=password
    #将用户保存到数据库中
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
    # 注册成功后吧数据保存到session中，让用户直接先登录
    session["user_id"]=user.id
    session["nick_name"]=user.mobile
    session["mobile"]=user.mobile
    # 返回登录成功
    return jsonify(errno=RET.OK,errmsg="注册成功")

# 登录
@passport_bp.route('/login',methods=['POST'])
def login():
    """
    获取数据
        获取手机号，未加密密码
    校验数据
        判断手机号码，密码是否为空
        手机号码正则
    逻辑处理
    判断用户是否存在
    密码传入哈希函数，然后判断
    返回值
    会犯js数据
    :return:
    """

    param_dict = request.json
    mobile=param_dict.get("mobile","")
    password = param_dict.get("password","")
    # 飞控判断
    if not ([mobile,password]):
        return jsonify(errno=RET.PARAMERR,errmsg="手机参数不足")
    if not re.match('1[3578][0-9]{9}',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg="手机号码格式不正确")
    try:
        user=User.query.filter(User.mobile==mobile).first()
    except Exception as e:
        return jsonify(errno=RET.DBERR,errmsg="对象查询出错")
    if not user:
        return jsonify(errno=RET.DBERR,errmsg="用户不存在")
    # 用户查询在了，是时候该验证密码了
    #TODO
    if not user.check_passowrd(password):
        return jsonify(errno=RET.DBERR,errmsg="密码填写错误")
    session["user_id"]=user.id
    session["nick_name"]=user.mobile
    session["mobile"]=user.mobile
    return jsonify(errno=RET.OK,errmsg="登录成功")


@passport_bp.route('/sms_code',methods=['POST'])
def send_sms_code():
    """
    获取参数
        获取图片验证码
        获取手机号码
    校验参数
        飞空判断
        正则判断
    逻辑处理
        从数据库中那出验证码进行对比
        image_code_id编码去redis中获取验证码的数据
        有值：删除
        没有值：让图片验证码过期

    返回值
    :return:
    """
    praram_dict =request.json
    mobile =praram_dict.get("mobile","")
    image_code = praram_dict.get("image_code","")


    image_code_id=praram_dict.get("image_code_id","")

    if not ([mobile,image_code,image_code_id]):
        current_app.logger.error("参数不足")
        return jsonify(errno=RET.DBERR, errmsg="参数不足")

    if not re.match('1[3578][0-9]{9}',mobile):
        current_app.logger.error("手机格式错误")
        return jsonify(errno=RET.DBERR,errmsg="手机格式错误")
    real_image_code=None
    try:
        real_image_code =redis_store.get("imageCodeId_%s"%image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="数据库查询验证码异常")
    if real_image_code:
        redis_store.delete("imageCodeId_%s"%image_code_id)
    else:
        return jsonify(errno=RET.NODATA,errmsg="图片验证码在redis中过期")

    real_image_code= str(real_image_code, encoding="utf8")
    if real_image_code.lower()!=image_code.lower():

        return jsonify(errno=RET.DATAERR,errmsg="图片验证码填写")
    try:
        user=User.query.filter(User.mobile==mobile).first()
    except  Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="查询用户异常")
    if user:
        return jsonify(errno=RET.DATAERR,errmsg="用户已经注册")
    sms_code=random.randint(0,999999)
    sms_code="%06d"%sms_code
    try:
        cpp=CCP()
        result = cpp.send_template_sms(mobile,[sms_code,constants.SMS_CODE_REDIS_EXPIRES],1)

    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR,errmsg="云通讯短信验证码发送失败")
    if result !=0:
        return jsonify(errno=RET.THIRDERR,errmsg="云通讯短信验证码未发送成功")
    try:
        redis_store.setex("SMS_CODE_%s"%mobile,constants.SMS_CODE_REDIS_EXPIRES,sms_code)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR,errmsg="短信验证码保存到数据库异常")
    return jsonify(errno=RET.OK,errmsg="短信验证码成功")
@passport_bp.route('/login_out',methods=['POST'])
def login_out():
    session.pop("user_id")
    session.pop("nick_name")
    session.pop("mobile")
    return jsonify(errno=RET.OK,errmsg="退出登录成功")